package sys
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	import WInterface.IClass;
	import WInterface.IConst;
	import WInterface.IReuse;
	import WInterface.ISingleton;
	import WInterface.ISys;

	/**
	 *对象管理类，进行单例和重用型对象的生成和管理。
	 *不支持类构造方法中含参数。使用该方法创建的类，同类型的类必须拥有不同的id
	 * @author 张进辉
	 * 
	 */
	public final class CoreObject implements ISys
	{
		/**单例型*/
		public static const SINGLETON:int = 1;
		/**复用型*/
		public static const REUSE:int = 2;
		/**常量型*/
		public static const CONST:int = 3;
		
		
		private var _debug:Boolean;
		/**单例对象组*/
		private var _singletonClass:Dictionary = new Dictionary();
		/**复用对象组*/
		private var _reuseClass:Dictionary = new Dictionary();
		/**常量对象组*/
		private var _constClass:Dictionary = new Dictionary();
		
		/**复用对象类型数量*/
		private var _reuseClsType:uint;
		/**复用对象实例数量*/
		private var _reuseTotal:uint;
		/**单例对象实例数量*/
		private var _singletonTotal:uint;
		
		/**当前应用*/
		private var _app:Sprite;
		
		private var curIntance:Object;
		/**
		 *构造函数 
		 * 
		 */		
		public function CoreObject(app:Sprite)
		{
			if(!Fcade.open)
				throw new Error("不要尝试实例化该类");
		}
		
		/**初始化类*/
		private function initClass():void
		{
			if(!curIntance) return;
			_app.addEventListener(Event.ENTER_FRAME,nextFrameHandler);
		}
		
		private function nextFrameHandler(e:Event):void
		{
			(curIntance as IClass).initialize();
			_app.removeEventListener(Event.ENTER_FRAME,nextFrameHandler);
			curIntance = null;
		}
		
		/**
		 *生成类 
		 * @param cls：类
		 * @param type：类型 单例   复用
		 * @param data：实例化类时附带的数据
		 * @return 
		 * 
		 */		
		public function createClass(cls:Class,type:int=1,data:Object=null):*
		{
			curIntance = null;
			if(type == SINGLETON)//单例类
			{
				curIntance = _singletonClass[cls];
				if(curIntance == null)
				{
					curIntance = new cls();
					if(!(curIntance is ISingleton)) throw new Error(getQualifiedClassName(curIntance)+'未实现ISingleton接口');
					_singletonClass[cls] = curIntance;
					(curIntance as ISingleton).reload(data);
				}
			}
			else if(type == REUSE)//重用类的复用
			{
				var reuses:Array = _reuseClass[cls];
				if(reuses == null)
				{
					curIntance = new cls();
					if(!(curIntance is IReuse)) throw new Error(getQualifiedClassName(curIntance)+'未实现IReuse接口');
					reuses = [curIntance];
					_reuseClass[cls] = reuses;
					(curIntance as IReuse).actived = true;
					(curIntance as IReuse).enabled(data);
				}
				//只有进行类获取时，才进行类释放
				for each (var item:IReuse in reuses) 
				{
					if(item.actived == false)
					{
						item.recover();
						item.actived = true;
						item.enabled(data);
						if(curIntance == null)//返回一个空闲对象
							curIntance = item;
					}
				}
				
				if(curIntance == null)//未能找到可用的对象，则创建新的对象
				{
					curIntance = new cls();
					reuses.push(curIntance);
					
					(curIntance as IReuse).actived = true;
					(curIntance as IReuse).enabled(data);
				}
				
			}
			else if(type == CONST)//常量类
			{
				var consts:Array = _reuseClass[cls];
				if(consts == null)
				{
					curIntance = new cls();
					if(!(curIntance is IConst)) throw new Error(getQualifiedClassName(curIntance)+'未实现IConst接口');
					consts = [curIntance];
					_constClass[cls] = consts;
					(curIntance as IConst).create(data);
				}
			}
			
			if(curIntance)
				initClass();
			
			return curIntance;
		}
		
		/**
		 * 快速创建复用类 
		 * @param cls: 类定义
		 * @param actived: 是否激活
		 * @return 
		 * 
		 */		
		public function simpleReuseCls(cls:Class,data:Object=null,actived:Boolean=true):Object
		{
			var dictArr:Array = _reuseClass[cls];
			if(dictArr == null)
			{
				dictArr = [];
				_reuseClass[cls] = dictArr;
			}
			
			var instance:Object = new cls();
			(instance as IReuse).actived = actived;
			if(actived)
				(instance as IReuse).enabled(data);
			dictArr.push(instance)
			
			return instance;
		}
		
		
		
		public function set debug(value:Boolean):void
		{
			_debug = value;
		}
		
		
		public function get debug():Boolean
		{
			return _debug;
		}
		
	}
}